package com.jfinalxueyuan.eclipse.caseconversion;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;

public class StrUtil {

	public static String cast(String str) {
		if (str == null || "".equals(str)) {
			return str;
		}
		if (str.contains("%")) {
			str = urlDecode(str);
		} else if ("@version".equals(str)) {
			str = versionComment(str);
		} else if ("@date".equalsIgnoreCase(str)) {
			str = dateComment(str);
		} else if ("一二三".equals(str)) {
			str = "零一二三四五六七八九";
		} else if ("a-z".equals(str)) {
			str = "abcdefghijklmnopqrstuvwxyz";
		} else if ("A-Z".equals(str)) {
			str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		} else if (isAllLetterOrNum(str)) {
			str = toggleFisrt(str);
		} else if (str.contains("\\u")) {
			str = ascii2Native(str);
		} else if (str.contains("\\\\")) {
			str = str.replace("\\\\", "/");
		} else if (str.contains("\\")) {
			str = str.replace("\\", "/");
		} else if (str.contains(",")) {
			str = str.replace(",", "\r\n");
		} else if (str.contains("_")) {
			str = underlineToCamel(str);
		} else if ("".equals(str.trim())) {
			str = str.replace(" ", "&nbsp;");
		} else if (str.startsWith("<") && str.endsWith(">")) {
			str = cdata(str);
		} else if (str.contains("==")) {
			str = equalsParam(str);
		} else if (str.contains("=")) {
			str = splitLine(str);
		} else if (!"@".equals(str.trim()) && str.startsWith("@")) {
			str = mybatisParam(str);
		} else if (isSin(str)) {
			str = str.replace("sin", "cos");
		} else if (isCos(str)) {
			str = str.replace("cos", "sin");
		} else {
			String string = null;
			try {
				string = new String(str.getBytes("UTF8"), "GBK");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			if (!str.equals(replaceEscape(string))) {
				str = replaceEscape(string);
			} else {
				str = toggleFisrt(str);
			}
		}
		return str;
	}

	private static String mybatisParam(String code) {
		if (!"@".equals(code.trim()) && code.startsWith("@")) {
			code = code.substring(1);
			int index = code.indexOf(" ");
			if (index == -1) {
				return code;
			}
			String left = code.substring(0, index);
			String right = code.substring(index + 1);
			left = left.trim();
			right = right.trim();
			StringBuilder sb = new StringBuilder();
			sb.append("@Param(\"");
			sb.append(right);
			sb.append("\")");
			sb.append(left);
			sb.append(" ");
			sb.append(right);
			return sb.toString();
		}
		return code;
	}

	private static String equalsParam(String code) {
		if (code.contains("==")) {
			int lastIndexOf = code.lastIndexOf("==");
			String left = code.substring(0, lastIndexOf);
			String right = code.substring(lastIndexOf + 2);
			left = left.trim();
			right = right.trim();
			if ("null".equals(right)) {
				return code;
			}
			if (!right.contains("\"")) {
				return code;
			}
			StringBuilder sb = new StringBuilder();
			sb.append(right);
			sb.append(".equals(");
			sb.append(left);
			sb.append(")");
			return sb.toString();
		}
		return code;
	}

	private static String versionComment(String str) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String now = sdf.format(new Date());
		return "@version " + now;
	}

	private static String dateComment(String str) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String now = sdf.format(new Date());
		return str.substring(0, 5) + " " + now;
	}

	private static String splitLine(String str) {
		int index = str.indexOf("=");
		StringBuilder sb = new StringBuilder();
		String before = str.substring(0, index);
		String after = str.substring(index + 1, str.length());
		before = before.trim();
		after = after.trim();
		sb.append(before);
		sb.append(" = null;");
		sb.append("\r\n");
		sb.append(before.substring(before.lastIndexOf(" ") + 1, before.length()));
		sb.append(" = ");
		sb.append(after);
		sb.append("\r\n");
		return sb.toString();
	}

	private static String cdata(String str) {
		if (str.length() > 2) {
			str = str.substring(1, str.length() - 1);
		}
		return "<![CDATA[" + str + "]]>";
	}

	private static String urlDecode(String str) {
		if (str == null || "".equals(str)) {
			return str;
		}
		if (str.contains("%")) {
			String decode = str;
			try {
				decode = URLDecoder.decode(str, "UTF-8");
				return decode;
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public static String ascii2Native(String str) {
		StringBuilder sb = new StringBuilder();
		int begin = 0;
		int index = str.indexOf("\\u");
		while (index != -1) {
			sb.append(str.substring(begin, index));
			sb.append(ascii2Char(str.substring(index, index + 6)));
			begin = index + 6;
			index = str.indexOf("\\u", begin);
		}
		sb.append(str.substring(begin));
		return sb.toString();
	}

	private static char ascii2Char(String str) {
		if (str.length() != 6) {
			throw new IllegalArgumentException("Ascii string of a native character must be 6 character.");
		}
		if (!"\\u".equals(str.substring(0, 2))) {
			throw new IllegalArgumentException("Ascii string of a native character must start with \"\\u\".");
		}
		String tmp = str.substring(2, 4);
		int code = Integer.parseInt(tmp, 16) << 8;
		tmp = str.substring(4, 6);
		code += Integer.parseInt(tmp, 16);
		return (char) code;
	}

	public static String toggleFisrt(String str) {
		boolean isLowCase = Character.isLowerCase(str.charAt(0));
		if (isLowCase) {
			str = upperFirst(str);
		} else {
			str = lowerFirst(str);
		}
		return str;
	}

	/**
	 * 大写首字母<br>
	 * 例如：str = name, return Name
	 * 
	 * @param str 字符串
	 * @return 字符串
	 */
	public static String upperFirst(String str) {
		if (null == str) {
			return null;
		}
		if (str.length() > 0) {
			char firstChar = str.charAt(0);
			if (Character.isLowerCase(firstChar)) {
				return Character.toUpperCase(firstChar) + str.substring(1, str.length());
			}
		}
		return str.toString();
	}

	/**
	 * 小写首字母<br>
	 * 例如：str = Name, return name
	 * 
	 * @param str 字符串
	 * @return 字符串
	 */
	public static String lowerFirst(String str) {
		if (null == str) {
			return null;
		}
		if (str.length() > 0) {
			char firstChar = str.charAt(0);
			if (Character.isUpperCase(firstChar)) {
				return Character.toLowerCase(firstChar) + str.substring(1, str.length());
			}
		}
		return str.toString();
	}

	public static String underlineToCamel(String str) {
		StringBuilder result = new StringBuilder();
		String ary[] = str.split("_");
		for (String sub : ary) {
			if (!str.contains("_")) {
				result.append(sub);
				continue;
			}
			if (result.length() == 0) {
				result.append(sub.toLowerCase());
			} else {
				result.append(sub.substring(0, 1).toUpperCase());
				result.append(sub.substring(1).toLowerCase());
			}
		}
		return result.toString();
	}

	public static String replacePunctuation(String str) {
		str = str.replace("，", ",");
		str = str.replace("。", ".");
		str = str.replace("；", ";");
		str = str.replace("：", ":");
		str = str.replace("！", "!");
		str = str.replace("“", "\"");
		str = str.replace("”", "\"");
		str = str.replace("【", "[");
		str = str.replace("】", "]");
		return str;
	}

	public static String replaceEscape(String str) {
		if ("，".equals(str)) {
			return ",";
		} else if ("。".equals(str)) {
			return ".";
		} else if ("；".equals(str)) {
			return ";";
		} else if ("：".equals(str)) {
			return ":";
		} else if ("！".equals(str)) {
			return "!";
		} else if ("“".equals(str)) {
			return "\"";
		} else if ("”".equals(str)) {
			return "\"";
		} else if ("【".equals(str)) {
			return "[";
		} else if ("】".equals(str)) {
			return "]";
		} else if ("\"".equals(str)) {
			return "&quot;";
		} else if ("&".equals(str)) {
			return "&amp;";
		} else if ("<".equals(str)) {
			return "&lt;";
		} else if (">".equals(str)) {
			return "&gt;";
		} else if (" ".equals(str)) {
			return "&nbsp;";
		} else if ("©".equals(str)) {
			return "&copy;";
		} else if ("&quot;".equals(str)) {
			return "\"";
		} else if ("&amp;".equals(str)) {
			return "&";
		} else if ("&lt;".equals(str)) {
			return "<";
		} else if ("&gt;".equals(str)) {
			return ">";
		} else if ("&nbsp;".equals(str)) {
			return " ";
		} else if ("&copy;".equals(str)) {
			return "©";
		} else if ("实心三角".equals(str)) {
			return "▲";
		} else if ("实心倒立三角".equals(str)) {
			return "▼";
		} else if ("实心圆形".equals(str)) {
			return "●";
		} else if ("实心菱形".equals(str)) {
			return "◆";
		} else if ("实心方形".equals(str)) {
			return "■";
		} else if ("实心五角".equals(str)) {
			return "★";
		} else if ("空心三角".equals(str)) {
			return "△";
		} else if ("空心倒立三角".equals(str)) {
			return "▽";
		} else if ("空心圆形".equals(str)) {
			return "○";
		} else if ("空心菱形".equals(str)) {
			return "◇";
		} else if ("空心方形".equals(str)) {
			return "□";
		} else if ("空心五角".equals(str)) {
			return "☆";
		} else {
			return str;
		}
	}

	private static boolean isSin(String str) {
		if (str == null || "".equals(str.trim())) {
			return false;
		}
		if ("sin".equals(str)) {
			return true;
		}
		int len = str.length();
		if (len <= 3) {
			return false;
		}
		int indexOf = str.indexOf("sin");
		if (indexOf == -1) {
			return false;
		}
		if (indexOf == 0) {
			if (!isLetterOrNumber(str.charAt(3))) {
				return true;
			} else {
				return false;
			}
		}
		if (indexOf == len - 3 && !isLetterOrNumber(str.charAt(indexOf - 1))) {
			return true;
		}
		if (!isLetterOrNumber(str.charAt(indexOf - 1)) && !isLetterOrNumber(str.charAt(indexOf + 3))) {
			return true;
		}
		return false;
	}

	private static boolean isCos(String str) {
		if (str == null || "".equals(str.trim())) {
			return false;
		}
		if ("cos".equals(str)) {
			return true;
		}
		int len = str.length();
		if (len <= 3) {
			return false;
		}
		int indexOf = str.indexOf("cos");
		if (indexOf == -1) {
			return false;
		}
		if (indexOf == 0) {
			if (!isLetterOrNumber(str.charAt(3))) {
				return true;
			} else {
				return false;
			}
		}
		if (indexOf == len - 3 && !isLetterOrNumber(str.charAt(indexOf - 1))) {
			return true;
		}
		if (!isLetterOrNumber(str.charAt(indexOf - 1)) && !isLetterOrNumber(str.charAt(indexOf + 3))) {
			return true;
		}
		return false;
	}

	private static boolean isLetterOrNumber(char charAt) {
		return Character.isLetterOrDigit(charAt);
	}

	private static boolean isAllLetterOrNum(String str) {
		if (str == null || "".equals(str.trim())) {
			return false;
		}
		int len = str.length();
		if (len == 1) {
			char ch = str.charAt(0);
			if (ch >= '0' && ch <= '9') {
				return false;
			} else if (ch >= 'a' && ch <= 'z') {
				return true;
			} else if (ch >= 'A' && ch <= 'Z') {
				return true;
			} else {
				return false;
			}
		}
		char ch = str.charAt(0);
		if (ch >= '0' && ch <= '9') {
			return false;
		}
		if (!isLetter(ch)) {
			return false;
		}
		for (int i = 1; i < str.length(); i++) {
			char charAt = str.charAt(i);
			if (!isLetterOrNumberClassic(charAt)) {
				return false;
			}
		}
		return true;
	}

	private static boolean isLetter(char ch) {
		if (ch >= 'a' && ch <= 'z') {
			return true;
		}
		if (ch >= 'A' && ch <= 'Z') {
			return true;
		}
		return false;
	}

	private static boolean isLetterOrNumberClassic(char charAt) {
		if (isLetter(charAt)) {
			return true;
		}
		if (charAt >= '0' && charAt <= '9') {
			return true;
		}
		return false;
	}
}
